class Calculator {
  public calcContainer: HTMLDivElement;
  private output: HTMLDivElement;
  private span: HTMLSpanElement;
  public n1: string = null;
  public n2: string = null;
  public operator: string;
  public result: string = null;
  public keys: Array<Array<string>>/*数组成员必须是数组成员全为字符串的数组*/ = [["clear", "÷"], ["7", "8", "9", "x"], ["4", "5", "6", "-"], ["1", "2", "3", "+"], ["0", ".", "="]];

  constructor() {
    this.createContainer();
    this.createOutput();
    this.createButtons();
    this.bindEvents();
  }

  createButton(text: string, container: HTMLElement, className?: string) {
    const button: HTMLButtonElement = document.createElement('button');
    button.textContent = text;
    if(className) {
      button.className = className;
    }
    container.appendChild(button);
    return button;
  }

  createContainer(){
    const calcContainer:HTMLDivElement = document.createElement('div');
    calcContainer.classList.add('calculator');
    document.body.appendChild(calcContainer);
    this.calcContainer = calcContainer;
  }

  createOutput(){
    const output:HTMLDivElement/*←不写typescript也会推测*/ = document.createElement('div');
    output.classList.add('output');
    const span: HTMLSpanElement = document.createElement('span');
    span.textContent = '0';
    output.appendChild(span);
    this.calcContainer.appendChild(output);
    this.output = output;
    this.span = span;
  }

  createButtons(){
    this.keys.forEach((textList: Array<string>) => {
      const div: HTMLDivElement = document.createElement('div');
      div.classList.add('row');
      textList.forEach((text: string) => {
        this.createButton(text, div, `button text-${text}`);
      });
      this.calcContainer.appendChild(div);
    });
  }

  bindEvents(){
    this.calcContainer.addEventListener('click', (event) => {
      if(event.target instanceof HTMLButtonElement) {
        const button: HTMLButtonElement = event.target;
        const text = button.textContent/*event.target并不一定有textContent属性,故这里用instanceof进行了类型保护,确保了button的类型*/;

        this.updateNumbersOrOperator(text);
      }
    });
  }

  updateN(which:string, text:string):void{
    if (this[which]) {
      this[which] += text;
    } else {
      this[which] = text;
    }
    this.span.textContent = this[which].toString();
  }

  updateNumbers(text:string){
    if (this.operator) {
      this.updateN('n2', text);
    } else {
      this.updateN('n1', text);
    }
  }

  updateResult(){
    let result;
    const n1 = parseFloat(this.n1);
    const n2 = parseFloat(this.n2);
    if (this.operator === '+') {
      result = n1 + n2;
    } else if (this.operator === '-') {
      result = n1 - n2;
    } else if (this.operator === 'x') {
      result = n1 * n2;
    } else if (this.operator === '÷') {
      result = n1 / n2;
    }
    result = result.toPrecision(12).replace(/0+$/,'').replace(/0+e/g,'e');
    if(n2 === 0) {
      result = '不是数字';
    }
    this.span.textContent = result.toString();
    this.n1 = null;
    this.n2 = null;
    this.operator = null;
    this.result = result;
  }

  updateOperator(text:string){
    if(!this.n1) {
      this.n1 = this.result;
    }
    this.operator = text;
  }

  updateNumbersOrOperator(text: string) {
    if ('0123456789.'.indexOf(text) >= 0) {
      this.updateNumbers(text);
    } else if ('+-x÷'.indexOf(text) >= 0) {
      this.updateOperator(text);
    } else if ('='.indexOf(text) >= 0) {
      this.updateResult();
    }else if(text === 'Clear'){
      this.n1 = null;
      this.n2 = null;
      this.operator = null;
      this.result = null;
      this.span.textContent = '0';
    }
  }
}


new Calculator();
